#ifndef TYPEPOINT_H_INCLUDED
#define TYPEPOINT_H_INCLUDED

#include <random>
#include <cmath>

static constexpr int32_t rand_seed = 19260817;

namespace FloatPoint
{
constexpr double EPS = 1e-5;

template <typename T>
bool abs(const T & x)
{
    return (x < 0 ? -x : x);
}

template <typename T>
bool equalEps(const T & lhs, const T & rhs)
{
    return abs(lhs - rhs) < EPS;
}

}
struct TPoint3DCartesian;

struct TPoint3DSphere
{
    double r, theta, phi;
    explicit TPoint3DSphere(const TPoint3DCartesian & p);
    bool operator == (const TPoint3DSphere & rhs) const;
    bool operator < (const TPoint3DSphere & rhs) const;
};

struct TPoint3DCartesian
{
    double x, y, z;
    explicit TPoint3DCartesian(const TPoint3DSphere & p);
    bool operator == (const TPoint3DCartesian & rhs) const;
    bool operator < (const TPoint3DCartesian & rhs) const;
};


inline std::pair <double, double> GetRandomPointPolar2D()
{
    static std::minstd_rand engine(rand_seed);
    static std::uniform_real_distribution <double> R_distribution (-2,2);
    static std::uniform_real_distribution <double> theta_distribution (-M_PI,M_PI);

    return {R_distribution(engine), theta_distribution(engine)};
}

inline std::pair <double, double> GetRandomPointCartesian2D()
{
    static std::minstd_rand engine(rand_seed);
    static std::uniform_real_distribution <double> R_distribution (-1,1);

    return {R_distribution(engine), R_distribution(engine)};
}

inline bool IsHit(double prob)
{
    static std::random_device rd;
    static std::minstd_rand engine(rd());
    static std::uniform_real_distribution <double> distribution (0,1);
    return distribution(engine) < prob;
}

inline std::pair <double, double> To2DCartesian(double R, double theta)
{
    double x, y;
    x = R * std::cos(theta);
    y = R * std::sin(theta);
//    std::cout << x << " " << y << std::endl ;
    return {x, y};
}

inline std::pair <double, double> To2DPolar(double x, double y)
{
    return {std::sqrt(x * x + y * y), x == 0 ? 0 : std::atan(y / x)};
}

#endif // TYPEPOINT_H_INCLUDED
